<template>
    <view class="m-cart-edit-container">
        <view class="m-cart-edit">
            <text v-show="edit" @click="edit = false">编辑</text>
            <text v-show="!edit" @click="edit = true">完成</text>
        </view>
    </view>
    <m-list :border="false">
        <m-list-item
            :border="false"
            v-for="cart in selTree.childrens"
            direction="column"
            :card="true"
            card-padding="20rpx"
        >
            <template v-slot:header v-if="(cart.val as ProductGroup).activity">
                <view class="m-cart-category m-col-margin-lg">
                    <m-circle-check-box
                        v-model="cart.val.checked"
                        class="m-cart-item-radio m-row-margin-sm"
                        @change="radioChange(cart)"
                    />
                    <uni-tag
                        :text="CartFavorCulcalute.getTypeDesc(<CartProductItem[]>cart.childrens?.map(v=>v.val))"
                        size="small"
                        type="error"
                        class="m-cart-category-tag"
                    />
                    <text class="m-cart-category-title">
                        {{
                            CartFavorCulcalute.getActivityTitle(cart.childrens?.map((v) => v.val) as CartProductItem[])
                        }}
                    </text>
                    <uni-icons type="right" size="14" />
                </view>
            </template>
            <template v-slot:body>
                <view
                    class="m-cart-item m-col-margin-max"
                    v-for="item in cart.childrens"
                    @longpress.stop="deleteProduct(item)"
                >
                    <m-circle-check-box
                        v-model="item.val.checked"
                        class="m-cart-item-radio m-row-margin-sm"
                        @change="radioChange(item)"
                    />
                    <image class="m-product-img" :src="(item.val as CartProductItem).productInfo.imageUrl" />
                    <view class="m-product m-row-margin-sm">
                        <view class="m-product-detail m-row-margin-sm">
                            <view class="m-product-detail-base">
                                <text class="m-product-detail-title m-row-margin-sm">
                                    {{ (item.val as CartProductItem).productInfo.title }}
                                </text>
                                <view class="m-product-detail-specs">
                                    <m-tag
                                        v-for="spec in (item.val as CartProductItem).specs"
                                        class="m-row-margin-sm"
                                        icon="bottom"
                                        :text="spec.name"
                                        @click="specClick(item.val as CartProductItem)"
                                    ></m-tag>
                                </view>
                                <view class="m-product-detail-service" v-if="(item.val as CartProductItem).userService">
                                    <m-tag
                                        :text="(item.val as CartProductItem).userService!.title"
                                        type="error"
                                        :circle="false"
                                        color="#fff"
                                    />
                                </view>
                            </view>
                            <view class="m-product-detail-price-layout">
                                <text class="m-product-detail-price">
                                    {{ (item.val as CartProductItem).productInfo.price }}
                                </text>
                                <uni-number-box
                                    v-model="(item.val as CartProductItem).count"
                                    :min="1"
                                    :max="(item.val as CartProductItem).productInfo.quantity"
                                />
                            </view>
                        </view>
                    </view>
                </view>
            </template>
            <template v-slot:footer>
                <view v-if="(<ProductGroup>cart.val).activity" class="m-cart-activity m-col-margin-lg">
                    <m-tag padding-size="large" size="normal">
                        <text class="m-cart-activity-tag-favor-txt">优惠</text>
                        <text class="m-row-margin-sm">
                            {{
                                CartFavorCulcalute.getActivitySubTitle(
                                    cart.childrens?.map((v) => v.val) as CartProductItem[]
                                )
                            }}
                        </text>
                    </m-tag>
                </view>
            </template>
        </m-list-item>
    </m-list>
    <m-bottom-pannel :height="settleHeight" v-show="showTotalPanel">
        <view class="m-settle">
            <view class="m-settle-selall">
                <m-circle-check-box
                    v-model="selTree.val.checked"
                    class="m-cart-item-radio m-row-margin-sm"
                    @change="radioChange(selTree)"
                />
                <text class="m-settle-sel-all">全选</text>
            </view>
            <view class="m-settle-right" v-show="edit">
                <view @click="priceDetail" class="m-settle-right-price">
                    <view>
                        <view>
                            总计：
                            <text class="m-settle-right-total-price">￥{{ realPrice }}</text>
                        </view>
                        <view class="m-settle-right-favor" v-if="totalFavorPrice > 0">
                            已优惠￥{{ totalFavorPrice }}
                        </view>
                    </view>
                    <uni-icons v-if="!priceDetailOpen" type="bottom" color="" size="14" class="m-row-margin-lg" />
                    <uni-icons v-if="priceDetailOpen" type="top" color="" size="14" class="m-row-margin-lg" />
                </view>
                <button class="m-settle-button" :disabled="settleDisabled">去结算({{ productCount }})</button>
            </view>
            <view class="m-settle-right" v-show="!edit">
                <button class="m-settle-button m-row-margin-base" @click="favoriteProduct">移至收藏</button>
                <button class="m-settle-button" @click="deleteProduct()">删除</button>
            </view>
        </view>
    </m-bottom-pannel>
    <cart-price-detail-pannel
        ref="priceDetailRef"
        :bottom="settleHeight"
        :total-price="totalPrice"
        :favors="favors"
        @change="(val) => (priceDetailOpen = val.show)"
    ></cart-price-detail-pannel>
    <cart-spec-pannel ref="cartSpecRef" @change="(val) => (showTotalPanel = !val.show)"></cart-spec-pannel>
</template>

<script lang="ts" setup>
import { ref, computed, shallowRef, reactive, shallowReactive, type ComputedRef, watchEffect } from 'vue'
import MList from '@/components/common/MList.vue'
import MListItem from '@/components/common/MListItem.vue'
import MTag from '@/components/common/MTag.vue'
import { getCartItem } from '@/api/market'
import { addFavorite } from '@/api/user'
import Util from '@/util/Util'
import CartFavorCulcalute from './CartFavorCulcalute'
import MBottomPannel from '@/components/common/MBottomPannel.vue'
import MCircleCheckBox from '@/components/common/MCircleCheckBox.vue'
import Tree from '@/util/Tree'
import CartPriceDetailPannel from './CartPriceDetailPannel.vue'
import CartSpecPannel from './CartSpecPannel.vue'
//获取购物车数据，并分组
let selTree: Tree<CartTree> = Util.strengthenShallowReactive(new Tree({ checked: true }, undefined, []), 2)
let coupons: UserCoupon[]
const showTotalPanel = ref(true)
const edit = ref(true)
const settleHeight = '120rpx'
const productCount = ref(0)
const settleDisabled = ref(false)
const totalPrice = ref(0)
getCartItem().then((v) => {
    coupons = v.data?.coupons || []
    let res = v.data?.items
    if (res) {
        let cartItems: GroupEntity<ProductGroup, CartProductItem>[] = Util.group(
            res,
            (v) => ({ activity: v.activityInfo, checked: true }),
            (v) => (v.activity ? v.activity.id : Symbol())
        )
        //构建radio树
        cartItems.forEach((v) => {
            let activitySel: Tree = Util.strengthenShallowReactive(new Tree<CartTree>(v.key, selTree, []), 2)
            selTree.childrens?.push(activitySel)
            v.val.forEach((product) => {
                product.checked = true
                let productSel = Util.strengthenShallowReactive(new Tree<CartTree>(product, activitySel, undefined), 2)
                activitySel.childrens?.push(productSel)
            })
        })
        watchEffect(() => {
            let tempTotal = 0
            let tempCount = 0
            selTree
                .getAllLeaf()
                .filter((v) => v.val.checked! && v.val.hasOwnProperty('count'))
                .map((v) => <CartProductItem>v.val)
                .forEach((v) => {
                    tempTotal = tempTotal + v.count * v.productInfo.price
                    tempCount = tempCount + v.count
                })
            totalPrice.value = tempTotal
            productCount.value = tempCount
            settleDisabled.value = tempCount == 0
        })
    }
})

const totalFavorPrice = computed<number>(() => {
    let price: number = favors.value
        .map((v) => v.amount)
        .reduce((t1, t2) => {
            return t1 + t2
        }, 0)
    return Math.round(price)
})
const favors = computed<Array<Favor>>(() => {
    return calculateFavor(totalPrice.value)
})
const realPrice = computed<number>(() => {
    return Math.round(totalPrice.value - totalFavorPrice.value)
})

function radioChange(node: Tree<CartTree>) {
    node.accessPosterity((v) => {
        v.val.checked = node.val.checked
    })
    node.accessBrothers((v) => {
        let brother = v.every((k) => k.val.checked)
        let parent = v[0].parent
        if (parent) {
            if (brother) {
                parent.val.checked = true
            } else {
                parent.val.checked = false
            }
        }
    })
}

function calculateFavor(total: number): Array<Favor> {
    const favors: Favor[] = []
    //活动和单品券优惠
    selTree.childrens?.forEach((v) => {
        favors.push(
            ...CartFavorCulcalute.getFavor(<CartProductItem[]>v.childrens?.map((v) => v.val)).filter(
                (f) => !f.activity || f.activity.type != 3
            )
        )
    })
    let favorAmount: number = favors
        .map((v) => v.amount)
        .reduce((t1, t2) => {
            return t1 + t2
        }, 0)
    total = total - favorAmount

    //全场券优惠
    let couponAmount = -1
    let desCoupon: UserCoupon
    if (coupons) {
        coupons
            .filter((v) => v.receive && total >= v.coupon.full)
            .forEach((v) => {
                let tempAmount = 0
                let tpl = v.coupon
                if (tpl.type == 1) {
                    tempAmount = tpl.amount
                } else if (tpl.type == 2) {
                    tempAmount = Math.round((1 - tpl.discount) * total)
                }
                if (tempAmount > couponAmount) {
                    couponAmount = tempAmount
                    desCoupon = v
                }
            })
    }
    if (couponAmount > -1) {
        favors.push({
            type: 2,
            coupon: desCoupon!,
            amount: couponAmount
        })
    }
    return favors
}
const priceDetailRef = ref<InstanceType<typeof CartPriceDetailPannel> | null>(null)
const priceDetailOpen = ref(false)
function priceDetail() {
    if (priceDetailOpen.value) {
        priceDetailRef.value?.close()
        priceDetailOpen.value = false
    } else {
        priceDetailRef.value?.open()
        priceDetailOpen.value = true
    }
}
const cartSpecRef = ref<InstanceType<typeof CartSpecPannel> | null>(null)
function specClick(val: CartProductItem) {
    cartSpecRef.value?.open(val)
}
function favoriteProduct() {
    let productids = selTree
        .getAllLeaf()
        .filter((v) => v.val.checked!)
        .map((v) => (<CartProductItem>v.val).productInfo.id)
        .join(',')
    addFavorite(productids).then((v) => {
        uni.showToast({
            title: '收藏成功',
            icon: 'success'
        })
    })
}
function deleteProduct(product?: Tree<CartTree>) {
    if (product) {
        uni.showModal({
            title: '警告',
            content: '确定删除该商品吗？',
            success: function (res) {
                if (res.confirm) {
                    selTree.deleteNode(product)
                }
            }
        })
    } else {
        uni.showModal({
            title: '警告',
            content: '确定删除所选商品吗？',
            success: function (res) {
                if (res.confirm) {
                    selTree
                        .getAllLeaf()
                        .filter((v) => v.val.checked!)
                        .forEach((v) => {
                            v.parent?.deleteNode(v)
                        })
                }
            }
        })
    }
}
</script>

<style lang="scss" scoped>
.m-cart-category {
    line-height: 44rpx;
    display: flex;
    align-items: center;
}
.m-cart-category-tag {
    margin-right: 20rpx;
}
.m-cart-category-sub-title {
    font-size: $uni-font-size-sm;
    color: $uni-color-subtitle;
}
.m-cart-category-title {
    font-size: $uni-font-size-base;
    line-height: 28rpx;
}
.m-cart-item {
    display: flex;
    flex-direction: row;
    align-items: center;
    width: 100%;
}
.m-product-img {
    width: 210rpx;
    height: 210rpx;
    flex-shrink: 0;
    border-radius: $uni-border-radius-lg;
}
.m-product {
    display: flex;
    flex-direction: row;
    flex-grow: 1;
    align-self: stretch;
}
.m-product-detail {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: stretch;
}
.m-product-detail-price-layout {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
}
.m-product-detail-tags {
    display: flex;
    flex-direction: row;
    align-content: space-between;
    flex-wrap: wrap;
}
.m-cart-activity {
    text-align: right;
}
.m-cart-activity-tag-favor-txt {
    color: red;
}
.m-product-detail-title {
    font-size: $uni-font-size-base;
}
.m-product-detail-specs {
    font-size: $uni-font-size-sm;
}
.m-settle {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    padding: 40rpx;
    align-items: center;
    border-top: 2rpx solid $uni-bg-color-grey;
    border-bottom: 2rpx solid $uni-bg-color-grey;
    box-sizing: border-box;
    height: 100%;
}
.m-settle-sel-all {
    font-size: 46rpx;
}
.m-settle-right {
    display: flex;
    flex-direction: row;
    align-items: center;
}
.m-settle-right-favor {
    font-size: 20rpx;
}
.m-settle-right-total-price {
    font-weight: 700;
}
.m-settle-selall {
    display: flex;
    flex-direction: row;
    align-items: center;
}
.m-settle-right-price {
    display: flex;
    flex-direction: row;
    align-items: center;
}
.m-cart-edit-container {
    height: 76rpx;
}
.m-cart-edit {
    text-align: right;
    font-size: $uni-font-size-lg;
    background-color: $uni-bg-color;
    top: 0rpx;
    width: 750rpx;
    color: black;
    position: fixed;
    z-index: $m-z-index-l1;
    box-sizing: border-box;
    line-height: 66rpx;
    padding-right: 20rpx;
}
</style>
